package xyj.sparrow.client.handler;

import xyj.sparrow.client.config.AppConf;
import xyj.sparrow.common.netty.bean.BaseMsg;
import xyj.sparrow.common.netty.bean.Register;
import xyj.sparrow.common.netty.bean.Request;
import xyj.sparrow.common.netty.bean.Response;
import cn.hutool.core.util.StrUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import xyj.sparrow.client.annotation.Service;
import xyj.sparrow.client.proxy.HandlerBeanDefinitionRegistry;
import xyj.sparrow.client.service.IRegisterService;
import xyj.sparrow.client.util.SpringContextUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @ClassName NettyClientHandler
 * @Description TODO
 * @Author Jim
 * @Date 2021/1/12 14:34
 * @Version 1.0.0
 **/
@Slf4j
public class NettyClientHandler extends SimpleChannelInboundHandler<BaseMsg> {
//    private final ConcurrentHashMap<String, SynchronousQueue<Object>> requestMap = new ConcurrentHashMap<>();

    /**
     * 连接成功
     * 发送注册信息
     *
     * @param ctx
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        log.info("客户端连接成功");
        IRegisterService iRegisterService = SpringContextUtil.getBean(IRegisterService.class);
        AppConf conf = SpringContextUtil.getBean(AppConf.class);
        String appId = conf.getAppId();
        List<Register> registers = new ArrayList<>();
        //扫描
        Collection<Class<?>> services = HandlerBeanDefinitionRegistry.listService();
        for (Class<?> service : services) {
            Register register = new Register();
            Service annotation = service.getAnnotation(Service.class);
            register.setAppId(StrUtil.isBlank(annotation.appId()) ? appId : annotation.appId());
            register.setClassName(service.getName());
            register.setTaskId(annotation.taskId());
            registers.add(register);
        }
        iRegisterService.register(registers, null);
    }


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, BaseMsg msg) {
        //处理回调
        if (msg instanceof Request) {
            //处理调度
            scheduling(ctx, (Request) msg);
        } else {

            log.info("{}", msg.toString());
        }
        ctx.fireChannelRead(msg);

    }

    private void scheduling(ChannelHandlerContext ctx, Request request) {
        try {
            Class<?> clz = Class.forName(request.getClassName());
            Object object = clz.newInstance();
            Method method = clz.getMethod(request.getMethodName(), request.getParamTypes());
            Object invoke = method.invoke(object, request.getParams());
            send(ctx, invoke, request.getRequestId());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            log.error("", e);
            sendError(ctx, request.getRequestId());
        }
    }

    private void sendError(ChannelHandlerContext ctx, String requestId) {
    }

    private void send(ChannelHandlerContext ctx, Object invoke, String requestId) {
        Response response = new Response();
        response.setRequestId(requestId);
        response.setCode(1);
        response.setMsg("你好，执行成功");
        response.setObject(invoke);
        ctx.channel().writeAndFlush(response);
    }

    public void send(Channel channel, Request request) {
//        SynchronousQueue<Object> queue = new SynchronousQueue<>();
//        requestMap.put(request.getRequestId(), queue);
        channel.writeAndFlush(request);
//        return queue;
    }

}
